//元素绘制方法集合
import * as d3 from "d3";
import * as DEFAULT from "@/utils/graph/default";
import * as Node from "@/utils/graph/Node";
import { BTN_STROKE_WIDTH } from "@/utils/graph/default";

export function Drawer(ctx){

  let context = ctx;

  /**---------------------------------------------------------------------------
   * 绘制当前kgInfo所有元素
   */
  this.drawAll = function() {

    let nodes = context.kgInfo.visibleNodes;
    let links = context.kgInfo.visibleLinks;

    this.drawLink(links);
    console.log("-- finish drawLink --");

    this.drawLinkText(links);
    console.log("-- finish drawLinkText --");

    this.drawNode(nodes);
    console.log("-- finish drawNode --");

    this.drawNodeText(nodes);
    console.log("-- finish drawNodeText --");

    this.drawButtonGroup(nodes);
    console.log("-- finish drawButtonGroup --");

    this.drawToolButton();
    console.log("-- finish drawToolButton --")

  }

  /**-----------------------------------------------------------------------------
   * 绘制节点
   * @param nodes
   */
  this.drawNode = function(nodes) {
    let _this = context;

    _this.qaGraphNode.selectAll("circle").remove(); //先移除所有节点

    let node = _this.qaGraphNode.selectAll("circle").data(nodes, function(d) {
      return d.uuid;
    });
    node.exit().remove();
    let nodeEnter = node.enter().append("circle");

    node = nodeEnter.merge(node)
    node
        .style("fill", function(d) {
          return d.color;
        })
        .style("stroke", DEFAULT.NODE_STROKE_COLOR)
        .style("stroke-opacity", 0.6)
        .style("stroke-width", DEFAULT.NODE_STROKE_WIDTH)
        .style("z-index",-1)
        .attr("r", function(d) {
          return d.r;
        })
        .attr("uuid", function(d) {
          return d.uuid;
        })
      .append("title") // 为每个节点设置title
        .text(function(d) {
          return d.label;
        });
      _this.graphNode = node;
  }

  /**-----------------------------------------------------------------------------
   * 绘制节点文字
   * @param nodes
   */
  this.drawNodeText = function(nodes) {
    let _this = context;

    _this.qaGraphNodeText.selectAll("text").remove();

    let nodetext = _this.qaGraphNodeText
      .selectAll("text")
      .data(nodes, function(d) {
        return d.uuid;
      });
    nodetext.exit().remove();

    let nodetextEnter = nodetext.enter().append("text");

    nodetext = nodetextEnter.merge(nodetext).text(function(d) {
      return d.label;
    });

    nodetext
        .style("fill", DEFAULT.NODE_FONT_COLOR)
        .style("pointer-events", "none") //取消鼠标对文字的感知
        .style("font-weight", Node.fontWeight)
        .style("z-index",0)
        .attr("class", "nodetext")
        .attr("font-family", DEFAULT.FONT_FAMILY)
        .attr("text-anchor", "middle")
        .attr("dy", Node.fontDy)
        .attr("font-size", Node.fontSize)
        .attr("uuid", function(d) {
          return d.uuid;
        })
        .text(function(d) {
          return d.label;
        })
      .append("title") // 为每个节点设置title
        .text(function(d) {
          return d.label;
        });
    _this.graphNodeText = nodetext;
  }

  /**-----------------------------------------------------------------------------
   * 绘制连接
   * @param links
   */
  this.drawLink = function(links) {
    let _this = context;

    _this.qaGraphLink.selectAll(".link").remove();

    let link = _this.qaGraphLink.selectAll(".link").data(links, function(d) {
      return d.uuid;
    });
    link.exit().remove();
    let linkEnter = link
      .enter()
      .append("path")
      .attr("class", "link")
      .attr("stroke-width", DEFAULT.LINK_STROKE_WIDTH)
      .attr("stroke", DEFAULT.MARKER_COLOR)
      .attr("fill", "none")
      .attr("uuid", function(d) {
        return d.uuid;
      })
      .attr("id", function(d) {
        return "invis_" + d.sId + "-" + d.uuid + "-" + d.tId;
      })
      .attr("marker-end", "url(#arrow)") // 箭头
    link = linkEnter.merge(link);
    _this.graphLink = link;
  }

  /**-----------------------------------------------------------------------------
   * 绘制连接文字
   * @param links
   */
  this.drawLinkText = function(links) {
    let _this = context;

    _this.qaGraphLinkText.selectAll(".linktext").remove();

    let linktext = _this.qaGraphLinkText
      .selectAll(".linktext")
      .data(links, function(d) {
        return d.uuid;
      });
    linktext.exit().remove();
    let linktextEnter = linktext
      .enter()
      .append("text")
      .attr("class", "linktext")
      .append("textPath")
      .attr("startOffset", "50%")
      .attr("text-anchor", "middle")
      .attr("uuid", function(d) {
        return d.uuid;
      })
      .attr("xlink:href", function(d) {
        return (
          "#invis_" + d.sId + "-" + d.uuid + "-" + d.tId
        );
      })
      .style("fill", DEFAULT.LINK_FONT_COLOR)
      .style("font-size", "10px")
      .style("z-index",-2)
      .style("pointer-events", "none") //取消鼠标对文字的感知
      .text(function(d) {
        return d.predicate;
      });
    linktext = linktextEnter.merge(linktext).text(function(d) {
      return d.predicate;
    });
    _this.graphLinkText = linktext;
  }

  /**-----------------------------------------------------------------------------
   * 绘制按钮盘面
   * @param context
   * @param nodes
   */
  this.drawButtonGroup = function(nodes) {
    let _this = context;

    d3.selectAll(".nodebutton").selectAll("use").remove();

    // d3.selectAll(".nodebutton >g").remove();
    let nodebutton = _this.nodebuttonGroup
      .selectAll(".nodebutton")
      .data(nodes, function(d) {
        return d.uuid;
      });
    nodebutton.exit().remove();
    let nodebuttonEnter = nodebutton
      .enter()
      .append("use") //  为每个节点组添加一个 use 子元素
      .attr("r", function(d) {
        return d.r;
      })
      .attr("uuid", function(d) {
        return d.uuid;
      })
      .attr("xlink:href", function(d) {
        return "#out_circle_" + d.r;
      }) //  指定 use 引用的内容
      .attr("class", function(d) {
        return "buttongroup out_buttongroup_" + d.uuid;
      })
      .classed("notshow", true)
      .style("visibility", "hidden");
    nodebutton = nodebuttonEnter.merge(nodebutton);
    _this.graphNodeButtonGroup = nodebutton;
  }

  /**-----------------------------------------------------------------------------
   * 绘制按钮组
   * @param context
   */
  this.drawToolButton = function() {
    let _this = context;

    let toolbarData = context.buttonGroupManager.toolbarData;

    //先删除所有为节点自定义的按钮组
    d3.selectAll("svg >defs").remove();
    let nodes = _this.kgInfo.nodes;
    let pie = d3.pie().value(function(d) {
      return d.value; //处理数据，指定value作为计算比例的字段
    });
    let piedata = pie(toolbarData);
    let nodeButtonGroup = _this.svg.append("defs");
    let nodeRArr = [];
    nodes.forEach(function(m) {

      if (!m.r) {
        m.r = DEFAULT.R;
      }
      //按半径分别定义每种按钮组的图标
      if (nodeRArr.indexOf(m.r) == -1) {
        nodeRArr.push(m.r);
        let nbtng = nodeButtonGroup.append("g").attr("id", "out_circle_" + m.r); //为每一个节点定制一个按钮组，在画按钮组的时候为其指定该id
        let buttonGroupEnter = nbtng
          .selectAll(".buttongroup")
          .data(piedata)
          .enter()
          .append("g")
          .attr("class", function(d) {
            return "action_" + d.data.code;
          });
        let arc = d3
          .arc()
          .innerRadius(m.r)
          .outerRadius(m.r + 30);
        buttonGroupEnter //定义按钮背景属性
          .append("path")
          .attr("id",m.uuid)
          .attr("d", function(d) {
            return arc(d);
          })
          .attr("fill", DEFAULT.BTN_COLOR)
          .style("opacity", DEFAULT.BTN_OPACITY)
          .style("cursor","pointer")
          .attr("stroke", DEFAULT.BTN_STROKE_COLOR)
          .attr("stroke-width", BTN_STROKE_WIDTH);
        buttonGroupEnter //定义按钮文字
          .append("text")
          .attr("transform", function(d) {
            return "translate(" + arc.centroid(d) + ")";
          })
          .attr("text-anchor", "middle")
          .text(function(d) {
            return d.data.name;
          })
          .style("pointer-events", "none") //取消鼠标对文字的感知
          .style("cursor","pointer")
          .style("fill", function() {
            return DEFAULT.BTN_FONT_COLOR;
          })
          .attr("font-family", DEFAULT.FONT_FAMILY)
          .attr("font-size", DEFAULT.BTN_FONT_SIZE);
      }
    });
  }


} //-- Drawer end